#include "http.hpp"

#define WWWROOT "./wwwroot/"

std::string RequestStr(const HttpRequest& req){
    std::stringstream ss;
    ss<<req._method<<" "<<req._path<<" "<<req._version<<"\r\n";
    for(auto& it : req._params){
        ss<<it.first<<": "<<it.second<<"\r\n";
    }
    for(auto& it : req._headers){
        ss<<it.first<<": "<<it.second<<"\r\n";
    }
    ss<<"\r\n";
    ss<<req._body;
    return ss.str();
}

void Hello(const HttpRequest& req,HttpResponse* rsp){
    rsp->SetContent(RequestStr(req),"text/plain");
}

void Login(const HttpRequest& req,HttpResponse* rsp){
    rsp->SetContent(RequestStr(req),"text/plain");
}

void PutFile(const HttpRequest& req,HttpResponse* rsp){
    std::string pathname = WWWROOT + req._path;
    Util::WriteFile(pathname, req._body);
    // rsp->SetContent(RequestStr(req),"text/plain");
}

void Delfile(const HttpRequest& req,HttpResponse* rsp){
    rsp->SetContent(RequestStr(req),"text/plain");
}

int main()
{
    HttpServer server(8085);
    server.SetThreadCount(3);
    server.SetBaseDir(WWWROOT);
    server.Get("/hello",Hello);
    server.Post("/login",Login);
    server.Put("/1234.txt",PutFile);
    server.Delete("/1234.txt",Delfile);
    server.Listen();
    return 0;
}























































// size_t Split(const std::string& str,const std::string& sep,std::vector<std::string>* arry){
//             size_t idx=0,pos=0;
//             while(idx<str.size()){
//                 pos=str.find(sep,idx);
//                 if(pos==std::string::npos){
//                     arry->push_back(str.substr(idx));
//                     return arry->size();
//                 }
//                 if(pos==idx){
//                     idx+=sep.size();
//                     continue;
//                 }
//                 arry->push_back(str.substr(idx,pos-idx));
//                 idx=pos+sep.size();
//             }
//             return arry->size();
// }
//  static bool ReadFile(const std::string& filename,std::string* buf){
//             std::ifstream ifs(filename,std::ios::binary);
//             if(ifs.is_open()==false){
//                 ERR_LOG("open %s file failed!",filename.c_str());
//                 return false;
//             }
//             size_t fsize=0;
//             ifs.seekg(0,ifs.end);
//             fsize=ifs.tellg();
//             ifs.seekg(0,ifs.beg);
//             buf->resize(fsize);
//             ifs.read(&(*buf)[0],fsize);
//             if(ifs.good()==false){
//                 ERR_LOG("read %s file failed!",filename.c_str());
//                 ifs.close();
//                 return false;
//             }
//             ifs.close();
//             return true;
// }
// static bool WriteFile(const std::string& filename,std::string& buf){
//             std::ofstream ofs(filename,std::ios::binary | std::ios::trunc);
//             if(ofs.is_open()==false){
//                 ERR_LOG("open %s file failed!",filename.c_str());
//                 return false;
//             }
//             ofs.write(buf.c_str(),buf.size());
//             if(ofs.good()==false){
//                 ERR_LOG("write %s file failed!",filename.c_str());
//                 ofs.close();
//                 return false;
//             }
//             ofs.close();
//             return true;
// }
//  static std::string UrlEncode(const std::string& url,bool convert_space_to_plus){
//             std::string res;
//             for(auto &c : url){
//                 if(c=='-' || c=='_' || c=='.' || c=='~' || isalnum(c)){
//                     res+=c;continue;
//                 }
//                 if(c==' ' && convert_space_to_plus){
//                     res+='+';continue;
//                 }
//                 //剩下的字符都是需要编码成为 %HH 格式
//                 char tmp[4]={0};
//                 snprintf(tmp,4,"%%%02X",c);
//                 res+=tmp;
//             }
//             return res;
// }
// static  char HEXTOI(char c){
//     if(c>='0'&&c<='9'){
//         return c-'0';
//     }else if(c>='a'&&c<='z'){
//         return c-'a'+10;
//     }else if(c>='A'&&c<='Z'){
//         return c-'A'+10;
//     }
//     return -1;
// }
// //URL解码
// static std::string UrlDecode(const std::string& url,bool convert_space_to_plus){
//     std::string res;
//     for(int i=0;i<url.size();i++){
//         if(url[i]=='+' && convert_space_to_plus){
//             res+=' ';continue;
//         }
//         if(url[i]=='%'){
//             char v1=HEXTOI(url[i+1]);
//             char v2=HEXTOI(url[i+2]);
//             char v=(v1<<4)+v2;
//             res+=v;
//             i+=2;
//             continue;
//         }
//         res+=url[i];
//     }
//     return res;
// }
// //响应状态码的描述信息获取
// static std::string StatuDesc(int statu){
//     std::unordered_map<int,std::string> _statu_msg={
//         {100,  "Continue"},
//         {101,  "Switching Protocol"},
//         {102,  "Processing"},
//         {103,  "Early Hints"},
//         {200,  "OK"},
//         {201,  "Created"},
//         {202,  "Accepted"},
//         {203,  "Non-Authoritative Information"},
//         {204,  "No Content"},
//         {205,  "Reset Content"},
//         {206,  "Partial Content"},
//         {207,  "Multi-Status"},
//         {208,  "Already Reported"},
//         {226,  "IM Used"},
//         {300,  "Multiple Choice"},
//         {301,  "Moved Permanently"},
//         {302,  "Found"},
//         {303,  "See Other"},
//         {304,  "Not Modified"},
//         {305,  "Use Proxy"},
//         {306,  "unused"},
//         {307,  "Temporary Redirect"},
//         {308,  "Permanent Redirect"},
//         {400,  "Bad Request"},
//         {401,  "Unauthorized"},
//         {402,  "Payment Required"},
//         {403,  "Forbidden"},
//         {404,  "Not Found"},
//         {405,  "Method Not Allowed"},
//         {406,  "Not Acceptable"},
//         {407,  "Proxy Authentication Required"},
//         {408,  "Request Timeout"},
//         {409,  "Conflict"},
//         {410,  "Gone"},
//         {411,  "Length Required"},
//         {412,  "Precondition Failed"},
//         {413,  "Payload Too Large"},
//         {414,  "URI Too Long"},
//         {415,  "Unsupported Media Type"},
//         {416,  "Range Not Satisfiable"},
//         {417,  "Expectation Failed"},
//         {418,  "I'm a teapot"},
//         {421,  "Misdirected Request"},
//         {422,  "Unprocessable Entity"},
//         {423,  "Locked"},
//         {424,  "Failed Dependency"},
//         {425,  "Too Early"},
//         {426,  "Upgrade Required"},
//         {428,  "Precondition Required"},
//         {429,  "Too Many Requests"},
//         {431,  "Request Header Fields Too Large"},
//         {451,  "Unavailable For Legal Reasons"},
//         {501,  "Not Implemented"},
//         {502,  "Bad Gateway"},
//         {503,  "Service Unavailable"},
//         {504,  "Gateway Timeout"},
//         {505,  "HTTP Version Not Supported"},
//         {506,  "Variant Also Negotiates"},
//         {507,  "Insufficient Storage"},
//         {508,  "Loop Detected"},
//         {510,  "Not Extended"},
//         {511,  "Network Authentication Required"}
//     };
//     auto it=_statu_msg.find(statu);
//     if(it!=_statu_msg.end()){
//         return it->second;
//     }
//     return "Unknow";
// }


// //根据文件名后缀名获取文件mime
// static std::string ExtMime(const std::string& filename){
//     std::unordered_map<std::string,std::string> _mime_msg={
//         {".aac",        "audio/aac"},
//         {".abw",        "application/x-abiword"},
//         {".arc",        "application/x-freearc"},
//         {".avi",        "video/x-msvideo"},
//         {".azw",        "application/vnd.amazon.ebook"},
//         {".bin",        "application/octet-stream"},
//         {".bmp",        "image/bmp"},
//         {".bz",         "application/x-bzip"},
//         {".bz2",        "application/x-bzip2"},
//         {".csh",        "application/x-csh"},
//         {".css",        "text/css"},
//         {".csv",        "text/csv"},
//         {".doc",        "application/msword"},
//         {".docx",       "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
//         {".eot",        "application/vnd.ms-fontobject"},
//         {".epub",       "application/epub+zip"},
//         {".gif",        "image/gif"},
//         {".htm",        "text/html"},
//         {".html",       "text/html"},
//         {".ico",        "image/vnd.microsoft.icon"},
//         {".ics",        "text/calendar"},
//         {".jar",        "application/java-archive"},
//         {".jpeg",       "image/jpeg"},
//         {".jpg",        "image/jpeg"},
//         {".js",         "text/javascript"},
//         {".json",       "application/json"},
//         {".jsonld",     "application/ld+json"},
//         {".mid",        "audio/midi"},
//         {".midi",       "audio/x-midi"},
//         {".mjs",        "text/javascript"},
//         {".mp3",        "audio/mpeg"},
//         {".mpeg",       "video/mpeg"},
//         {".mpkg",       "application/vnd.apple.installer+xml"},
//         {".odp",        "application/vnd.oasis.opendocument.presentation"},
//         {".ods",        "application/vnd.oasis.opendocument.spreadsheet"},
//         {".odt",        "application/vnd.oasis.opendocument.text"},
//         {".oga",        "audio/ogg"},
//         {".ogv",        "video/ogg"},
//         {".ogx",        "application/ogg"},
//         {".otf",        "font/otf"},
//         {".png",        "image/png"},
//         {".pdf",        "application/pdf"},
//         {".ppt",        "application/vnd.ms-powerpoint"},
//         {".pptx",       "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
//         {".rar",        "application/x-rar-compressed"},
//         {".rtf",        "application/rtf"},
//         {".sh",         "application/x-sh"},
//         {".svg",        "image/svg+xml"},
//         {".swf",        "application/x-shockwave-flash"},
//         {".tar",        "application/x-tar"},
//         {".tif",        "image/tiff"},
//         {".tiff",       "image/tiff"},
//         {".ttf",        "font/ttf"},
//         {".txt",        "text/plain"},
//         {".vsd",        "application/vnd.visio"},
//         {".wav",        "audio/wav"},
//         {".weba",       "audio/webm"},
//         {".webm",       "video/webm"},
//         {".webp",       "image/webp"},
//         {".woff",       "font/woff"},
//         {".woff2",      "font/woff2"},
//         {".xhtml",      "application/xhtml+xml"},
//         {".xls",        "application/vnd.ms-excel"},
//         {".xlsx",       "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
//         {".xml",        "application/xml"},
//         {".xul",        "application/vnd.mozilla.xul+xml"},
//         {".zip",        "application/zip"},
//         {".3gp",        "video/3gpp"},
//         {".3g2",        "video/3gpp2"},
//         {".7z",         "application/x-7z-compressed"}
//     };
//     size_t pos=filename.rfind('.');
//     if(pos==std::string::npos) return "application/octet-stream";
//     std::string str=filename.substr(pos);
//     auto it=_mime_msg.find(str);
//     if(it!=_mime_msg.end()){
//         return it->second;
//     }
//     return "application/octet-stream";
// }

// //判断一个文件是否是一个目录
// static bool IsDirectory(const std::string& filename){
//     struct stat st;
//     int ret=stat(filename.c_str(),&st);
//     if(ret<0){
//         return false;
//     }
//     return S_ISDIR(st.st_mode);
// }
// //判断一个文件是否是一个普通的文件
// static bool IsRegular(const std::string& filename){
//     struct stat st;
//     int ret=stat(filename.c_str(),&st);
//     if(ret<0){
//         return false;
//     }
//     return S_ISREG(st.st_mode);
// }
// //http请求的资源路径有效性判断
// static bool ValidPath(const std::string& path){
//     std::vector<std::string> dirsum;
//     int level=0;
//     Split(path,"/",&dirsum);
//     for(auto& dir : dirsum){
//         if(dir==".."){
//             level--;
//             if(level<0) return false;
//             continue;
//         }
//         level++;
//     }
//     return true;
// }

// int main()
// {
//     std::cout<<ValidPath("/index.html")<<std::endl;
//     std::cout<<ValidPath("/../index.html")<<std::endl;
//     std::cout<<ValidPath("../index.html")<<std::endl;
//     std::cout<<ValidPath("/html/../../index.html")<<std::endl;


//     // std::cout<<IsDirectory("testdir")<<std::endl;
//     // std::cout<<IsDirectory("test.cc")<<std::endl;
//     // std::cout<<IsRegular("testdir")<<std::endl;
//     // std::cout<<IsRegular("test.cc")<<std::endl;


//     // std::cout<<StatuDesc(404)<<std::endl;
//     // std::cout<<ExtMime("text.test.aaic")<<std::endl;
//     // std::cout<<ExtMime("text.test.aac")<<std::endl;

//     // std::string url="C++";
//     // std::string res=UrlEncode(url,true);
//     // std::string tmp=UrlDecode(res,true);
//     // std::cout<<res<<std::endl;
//     // std::cout<<tmp<<std::endl;
//     // std::string filename="./main.cc";
//     // std::string cur;
//     // int ret=ReadFile(filename,&cur);
//     // WriteFile("./test.cc",cur)
//     // std::string str="abc";
//     // std::vector<std::string> arry;
//     // size_t ret=Split(str,",",&arry);
//     // for(auto& ch : arry) std::cout<<"["<<ch<<"]"<<std::endl;
//     return 0;
// }
